home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 020 / modula.arc / PUZZ.MOD < prev    next >
Encoding:
Text File  |  1986-08-19  |  8.6 KB  |  389 lines

  1.  
  2. MODULE Puzz2B;
  3.  
  4. (*  Puzz2B.Mod
  5.     04/11/1986
  6.     John Tal
  7.  
  8.     Version of Puzz2B.Mod  -  Generates Word search Puzzles
  9.  
  10.     Character Height & Width's are Adjustable
  11.  *)
  12.  
  13.  
  14. FROM InOut IMPORT WriteCard,OpenInput,Done,CloseInput,ReadString,ReadInt,
  15.                   WriteInt;
  16. FROM Terminal IMPORT WriteLn,WriteString;
  17. FROM Printer IMPORT OpenPrinter,ClosePrinter,PrintChar,PrintString,
  18.                     PrintTab,PrintTabMid,PrintLn;
  19. FROM Strings IMPORT Assign,CompareStr,Length;
  20.  
  21.  
  22. CONST
  23.   vertsiz = 20;
  24.   horzsiz = 39;
  25.  
  26.   Bound = 21845;
  27.  
  28. TYPE
  29.   st255 = ARRAY[0..255] OF CHAR;
  30.   st39  = ARRAY[0..39] OF CHAR;
  31.  
  32. VAR
  33.   words : ARRAY[1..vertsiz] OF st39;
  34.   samples : ARRAY[1..200] OF st39;
  35.   had : ARRAY[1..200] OF INTEGER;
  36.   d,curt,thisword,postry,xpos,ypos,direct,way,xinc,yinc,wordlen : INTEGER;
  37.   tchar,TitleLen,copies,curx,cury,filx,fily,i,f,e,jmp,donwords : INTEGER;
  38.   done,fits,ok2put,flips,tryingPos,figuring,filling : BOOLEAN;
  39.   tts,title : st39;
  40.   curchar : CHAR;
  41.   fname1 : st39;
  42.  
  43.  
  44.  
  45. (* ----------------
  46.  
  47.    CardRandom Procedures originally developed by John Beidler & Paul Jackowitz
  48.    of the University of Scranton.
  49.  
  50. *)
  51.  
  52.   Seed : ARRAY[1..2] OF CARDINAL;
  53.   Group, Number, I : CARDINAL;
  54.  
  55. PROCEDURE RandomThree() : CARDINAL;
  56. VAR
  57.   Product,Carry,I : CARDINAL;
  58. BEGIN
  59.   LOOP
  60.     Carry := 0;
  61.     FOR I := 1 TO 2 DO
  62.       Seed[I] := Seed[I] + Carry;
  63.       Product := 3 * Seed[I];
  64.       Carry := Product DIV Bound;
  65.       Seed[I] := Product MOD Bound;
  66.     END;
  67.     CASE Carry OF
  68.         0 : RETURN 0;
  69.       | 1 : RETURN 1;
  70.      ELSE
  71.     END;
  72.   END
  73. END RandomThree;
  74.  
  75. PROCEDURE InitSeed( V1,V2 : CARDINAL);
  76. BEGIN
  77.   Seed[1] := V1 MOD Bound;
  78.   Seed[2] := V2 MOD Bound;
  79. END InitSeed;
  80.  
  81. PROCEDURE CardRandom (V : CARDINAL) : CARDINAL;
  82. VAR
  83.   Current,Answer : CARDINAL;
  84. BEGIN
  85.   LOOP
  86.     Current := 1;
  87.     Answer := 0;
  88.     REPEAT
  89.       IF RandomThree() = 1 THEN
  90.         Answer := Answer + Current;
  91.       END;
  92.       Current := 2 * Current;
  93.     UNTIL Current > V;
  94.     IF Answer < V THEN
  95.       RETURN Answer;
  96.     END;
  97.   END;
  98. END CardRandom;
  99.  
  100.  
  101. (* --------- *)
  102.  
  103. PROCEDURE ToSpaces(VAR dest : ARRAY OF CHAR; i : CARDINAL);
  104. VAR
  105.  q : CARDINAL;
  106. BEGIN
  107.  IF i > 0 THEN
  108.    FOR q := 0 TO i-1 DO
  109.      dest[q] := ' ';
  110.    END;
  111.    dest[i] := CHR(0);
  112.  ELSE
  113.    dest[0] := CHR(0);
  114.  END;
  115. END ToSpaces;
  116.  
  117.  
  118. PROCEDURE setup;
  119. BEGIN
  120. WriteString('Clearing out string space.     Please stand-BY');
  121. WriteLn;
  122.   FOR d := 1 TO vertsiz DO
  123.     ToSpaces(words[d],horzsiz);
  124.   END;
  125.   FOR d := 1 TO 200 DO
  126.       ToSpaces(samples[d],horzsiz);
  127.       had[d] := 0;
  128.   END;
  129.  
  130.   WriteLn;
  131.   WriteString('Title FOR puzzle ');
  132.   ReadString(title);
  133.   WriteLn;
  134.   WriteString('Number OF Copies TO Print ');
  135.   ReadInt(copies);
  136.   WriteLn;
  137.   WriteString('File TO use ');
  138.   WriteLn;
  139.   OpenInput(fname1);
  140.   WriteLn;
  141.   curt := 1;
  142.   REPEAT
  143.     ReadString(tts);
  144.     WriteString(tts); WriteInt(curt,6); WriteLn;
  145.     samples[curt] := tts;
  146.     INC(curt);
  147.   UNTIL (curt > 100) OR (Length(tts) = 0);
  148.   DEC(curt);
  149.   CloseInput;
  150. END setup;
  151.  
  152.  
  153. PROCEDURE DoThis;
  154. VAR
  155.   t1 : INTEGER;
  156. BEGIN
  157.   REPEAT
  158.     INC(thisword);
  159.     t1 := had[thisword];
  160.   UNTIL t1 <> -1;
  161. END DoThis;
  162.  
  163.  
  164. PROCEDURE FigureDirect( direct : INTEGER ; VAR xinc,yinc : INTEGER);
  165. BEGIN
  166.   CASE direct OF
  167.     1 :  xinc := 1;
  168.          yinc := 0;
  169.  |  2 :  xinc := -1;
  170.          yinc := 0;
  171.  |  3 :  xinc := 0;
  172.          yinc := 1;
  173.  |  4 :  xinc := 0;
  174.          yinc := -1;
  175.  |  5 :  xinc := 1;
  176.          yinc := -1;
  177.  |  6 :  xinc := -1;
  178.          yinc := -1;
  179.  |  7 :  xinc := 1;
  180.          yinc := 1;
  181.  |  8 :  xinc := -1;
  182.          yinc := 1;
  183. END;  (* CASE direct OF *)
  184. END FigureDirect;
  185.  
  186.  
  187. PROCEDURE DoesItFit() : BOOLEAN;
  188. BEGIN
  189. fits := TRUE;
  190. CASE direct OF
  191.      1 : IF xpos + wordlen-1 > horzsiz THEN
  192.               fits := FALSE;
  193.          END;
  194.   |  2 : IF xpos - wordlen < 1 THEN
  195.               fits := FALSE;
  196.          END;
  197.   |  3 : IF ypos + wordlen-1 > vertsiz THEN
  198.               fits := FALSE;
  199.          END;
  200.   |  4 : IF ypos - wordlen < 1 THEN
  201.               fits := FALSE;
  202.          END;
  203.   |  5 : IF (xpos + wordlen-1 > horzsiz) OR (ypos-wordlen < 1) THEN
  204.               fits := FALSE;
  205.          END;
  206.   |  6 : IF (xpos - wordlen < 1) OR (ypos - wordlen < 1) THEN
  207.               fits := FALSE;
  208.          END;
  209.   |  7 : IF (xpos + wordlen-1 > horzsiz) OR (ypos + wordlen-1 > vertsiz) THEN
  210.               fits := FALSE;
  211.          END;
  212.   |  8 : IF (xpos - wordlen < 1) OR (ypos + wordlen-1 > vertsiz) THEN
  213.               fits := FALSE;
  214.          END;
  215. END; (* CASE direct OF *)
  216. RETURN fits;
  217. END DoesItFit;
  218.  
  219.  
  220. PROCEDURE IsItOk2() : BOOLEAN;
  221. VAR
  222.  isit : BOOLEAN;
  223. BEGIN
  224.   curx := xpos;
  225.   cury := ypos;
  226.   isit := TRUE;
  227.   FOR tchar := 0 TO wordlen-1 DO
  228.      curchar := samples[thisword][tchar];
  229.      IF (words[cury][curx] <> ' ') AND
  230.         (words[cury][curx] <> curchar) THEN
  231.            isit := FALSE;
  232.      END;
  233.      curx := curx + xinc;
  234.      cury := cury + yinc;
  235.   END; (* FOR tchar *)
  236.   RETURN isit;
  237. END IsItOk2;
  238.  
  239.  
  240. PROCEDURE swap(VAR a1,a2 : st39);
  241. VAR
  242.   temp : st39;
  243. BEGIN
  244.   Assign(a1,temp);  (* temp := a1 *)
  245.   Assign(a2,a1);    (* a1 := a2;   *)
  246.   Assign(temp,a2);  (* a2 := temp; *)
  247. END swap;
  248.  
  249. PROCEDURE output;
  250. BEGIN
  251.    FOR d := 1 TO vertsiz DO
  252.        PrintString(words[d]);
  253.        PrintLn;
  254.    END;
  255.  
  256.     FOR fily := 1 TO vertsiz DO
  257.         FOR filx := 1 TO horzsiz DO
  258.            IF words[fily][filx] = ' ' THEN
  259.                words[fily][filx] := CHR(CardRandom(26)+65);
  260.                (*
  261.                   delete(words[fily],filx,1);
  262.                   insert(CHR(TRUNC(random*25+65)),words[fily],filx);
  263.                *)
  264.            END;
  265.         END;
  266.     END;
  267.  
  268.     flips := TRUE;
  269.     WHILE flips DO
  270.       flips := FALSE;
  271.          FOR i := 1 TO curt-2 DO
  272.             IF CompareStr(samples[i],samples[i+1]) = 1 THEN
  273.                swap(samples[i],samples[i+1]);
  274.                flips := TRUE;
  275.             END;
  276.          END;
  277.     END;
  278.     TitleLen := 39 - (Length(title) DIV 2);
  279.  
  280.     FOR f := 1 TO copies DO
  281.       PrintChar(CHR(12));
  282.       PrintTab(TitleLen,title);
  283.       PrintLn;
  284.       PrintLn;
  285.       FOR d := 1 TO vertsiz DO
  286.           FOR e := 1 TO horzsiz DO
  287.               PrintChar(words[d][e]);
  288.               PrintChar(' ');
  289.           END;
  290.           PrintLn;
  291.           PrintLn;
  292.       END;   (* FOR d *)
  293.       PrintLn;
  294.       jmp := (curt-1) DIV 3;
  295.       FOR d := 1 TO jmp DO
  296.          PrintTab(5,samples[d]);
  297.          PrintTab(30,samples[d+jmp]);
  298.          PrintTab(65,samples[d+jmp*2]);
  299.          PrintLn;
  300.       END;
  301.     END;  (* FOR f *)
  302. END output;
  303.  
  304.  
  305. PROCEDURE getXY;
  306. BEGIN
  307.   xpos := INTEGER(CardRandom(horzsiz) + 1);
  308.           (* TRUNC(random*(horzsiz)-1)+1; *)
  309.   ypos := INTEGER(CardRandom(vertsiz) + 1);
  310.           (* TRUNC(random*(vertsiz)-1)+1; *)
  311. END getXY;
  312.  
  313.  
  314. PROCEDURE update;
  315. BEGIN
  316.   INC(direct);
  317.   INC(way);
  318.   IF direct = 9 THEN
  319.     direct := 1;
  320.   END;
  321.   IF way = 9 THEN
  322.      way := 1;
  323.      figuring := FALSE;
  324.   END;
  325. END update;
  326.  
  327.  
  328. BEGIN
  329.   InitSeed(5AE3H,4E7FH);
  330.   OpenPrinter;
  331.  
  332.   setup;
  333.   thisword := 0;
  334.   donwords := 0;
  335.   WHILE donwords < curt-1 DO
  336.      DoThis;   (* t1 = had[thisword] *)
  337.      wordlen := Length(samples[thisword]);
  338.      postry := 1;
  339.      tryingPos := TRUE;
  340.      WHILE tryingPos DO
  341.        getXY;
  342.        direct := INTEGER(CardRandom(7) + 1);
  343.                  (* TRUNC(random*7)+1; *)
  344.        way := 1;
  345.        figuring := TRUE;
  346.        WHILE figuring DO
  347.            FigureDirect(direct,xinc,yinc);
  348.            fits := DoesItFit();
  349.            IF fits THEN
  350.               ok2put := IsItOk2();
  351.               IF ok2put THEN
  352.                 curx := xpos;
  353.                 cury := ypos;
  354.                 FOR tchar := 0 TO wordlen-1 DO
  355.                   curchar := samples[thisword][tchar];
  356.                      (*
  357.                      delete(words[cury],curx,1);
  358.                      insert(curchar,words[cury],curx);
  359.                      *)
  360.                    words[cury][curx] := curchar;
  361.                    curx := curx + xinc;
  362.                    cury := cury + yinc;
  363.                 END;
  364.                 had[thisword] := -1;
  365.                 INC(donwords);
  366.                 WriteCard(donwords,6);
  367.                 figuring := FALSE;
  368.                 tryingPos := FALSE;
  369.               END; (* ok2put *)
  370.            END; (* fits *)
  371.            IF figuring THEN
  372.             update;
  373.            END;
  374.        END; (* figuring *)
  375.        IF tryingPos THEN
  376.          postry := postry + 1;
  377.          IF postry = 16 THEN
  378.             tryingPos := FALSE;
  379.          END;
  380.        END;
  381.      END; (* tryingPos *)
  382.   END;   (* donwords *)
  383.  
  384.   output;
  385.  
  386.   ClosePrinter;
  387.  
  388. END Puzz2B.
  389.